package org.jeecg.modules.monitoring.j_monitoring.gatewayData;

import com.alibaba.fastjson.JSONArray;
import com.sun.org.apache.bcel.internal.generic.I2F;
import com.xkcoding.http.util.StringUtil;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.config.sign.util.NoSslHttpUtils;
import org.jeecg.config.vo.HttpResult;
import org.jeecg.modules.monitoring.j_monitoring.entity.RealVirtualCluster;
import org.jeecg.modules.monitoring.j_monitoring.entity.RealVirtualHost;
import org.jeecg.modules.monitoring.j_monitoring.entity.RealVirtualItem;
import org.jeecg.modules.monitoring.j_monitoring.entity.fdnEntity.*;
import org.jeecg.modules.monitoring.j_monitoring.mapper.RealVirtualClusterMapper;
import org.jeecg.modules.monitoring.j_monitoring.mapper.RealVirtualHostMapper;
import org.jeecg.modules.monitoring.j_monitoring.mapper.RealVirtualItemMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 虚拟机获取数据
 */
@Component
public class Virtual {
    @Autowired
    private Environment env;
    @Resource
    private RealVirtualClusterMapper clusterMapper;

    @Resource
    private RealVirtualHostMapper hostMapper;

    @Resource
    private RealVirtualItemMapper itemMapper;

    private String childMos = "/ng/mo/childMOs";

    private String path = "D:\\jsonFile\\network.txt";

    private String deviceMonitors = "/ng/integration/deviceMonitors";

    /**
     * 获取下级请求
     *
     * @param fdn
     * @return
     */
    public List<VirtuChildResult> getChildMOs(String fdn) {

        String url = env.getProperty("gatewaySystem.url");

        String header = env.getProperty("gatewaySystem.header");

        String queryUrl = url + childMos + "?fdn=" + fdn;

        String json = "";
        if (!"prod".equals(env.getProperty("spring.profiles.active"))) {
            return new ArrayList<>();

        }
        HttpResult res = NoSslHttpUtils.noSslGet(queryUrl, header);
        json = res.getBody();


        try {
            List<VirtuChildResult> result = JSONArray.parseArray(json, VirtuChildResult.class);
            return result;

        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }

    }


    public DevicesMonitors getMonitors(String fdn) {

        String url = env.getProperty("gatewaySystem.url");

        String header = env.getProperty("gatewaySystem.header");

        String queryUrl = url + deviceMonitors + "?device_fdns=" + fdn;

        if (!"prod".equals(env.getProperty("spring.profiles.active"))) {
            return null;
        }

        HttpResult res = NoSslHttpUtils.noSslGet(queryUrl, header);
        String json = res.getBody();


        try {
            List<DevicesMonitors> monitorsList = JSONArray.parseArray(json, DevicesMonitors.class);
            return monitorsList.get(0);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 记录虚拟机集群参数
     * @param child
     */
    public RealVirtualCluster saveOrUpdateCluster(VirtulResultChild child,String ip){
        RealVirtualCluster cluster = clusterMapper.selectByFdn(child.getFdn());
        Boolean insert = false;
        if (cluster==null){
            cluster = new RealVirtualCluster();
            insert = true;
            cluster.setName(child.getLabel());
            cluster.setFdn(child.getFdn());
            cluster.setIp(ip);
            cluster.setId(UUID.randomUUID().toString().replace("-", ""));
        }


        BigDecimal total = new BigDecimal(0);
        BigDecimal used = new BigDecimal(0);
        BigDecimal mount = new BigDecimal(0);
        BigDecimal local = new BigDecimal(0);
        DevicesMonitors monitor = this.getMonitors(child.getFdn());
        for (DevicesCounters counters : monitor.getMonitors()){

            if ("VmwareCrHostsSummary".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("effectiveHosts".equals(devicesData.getName())){
                        //主机数
                        cluster.setHostNum(Double.valueOf(devicesData.getValue()).intValue());
                    }

                }

            }

            if ("VmwareCrHostsCpuSummary".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("utilizationCpu".equals(devicesData.getName())){
                        //cpu使用
                        cluster.setCpuUse(new BigDecimal(devicesData.getValue()));
                    }

                    if ("cpuThreads".equals(devicesData.getName())){
                        //cpu线程数
                        cluster.setCpuThreadNum(Double.valueOf(devicesData.getValue()).intValue());
                    }

                    if ("cpuCores".equals(devicesData.getName())){
                        //cpu核数
                        cluster.setCpuKernelNum(Double.valueOf(devicesData.getValue()).intValue());
                    }

                    if ("totalCpu".equals(devicesData.getName())){
                        //hz数
                        cluster.setCpuHzNum(Double.valueOf(devicesData.getValue()).intValue());
                    }

                    if ("usedCpu".equals(devicesData.getName())){
                        //hz数
                        cluster.setCpuUsed(new BigDecimal(devicesData.getValue()));
                    }

                }

            }


            if ("VmwareCrHostsMemorySummary".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("utilizationMemory".equals(devicesData.getName())){
                        //内存使用数
                        cluster.setMementUse(new BigDecimal(devicesData.getValue()));
                    }

                    if ("totalMemory".equals(devicesData.getName())){
                        //总内存
                        if ("MB".equals(devicesData.getUnit())){
                            cluster.setMementNum(Double.valueOf(devicesData.getValue()).intValue()/1024);
                        }else {
                            cluster.setMementNum(Double.valueOf(devicesData.getValue()).intValue());
                        }
                    }

                    if ("usedMemory".equals(devicesData.getName())){
                        //已使用内存
                        cluster.setMementUsed(this.unitGbConversion(devicesData.getValue(),devicesData.getUnit()));
                    }

                }

            }

            //存储资源
            if ("VmwareCrDatastore".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if (StringUtil.isEmpty(devicesData.getName())){
                        continue;
                    }

                    if ("Capacity".equals(devicesData.getName())){
                        //总数
                        total = total.add(this.unitConversion(devicesData.getValue(),devicesData.getUnit()));

                        //挂载数
                        if (counters.getName().contains("seagate") ||  counters.getName().contains("Seagate")){
                            mount = mount.add(this.unitConversion(devicesData.getValue(),devicesData.getUnit()));
                        }

                        if (counters.getName().contains("ISO") ||  counters.getName().contains("datastore")){
                            local = local.add(this.unitConversion(devicesData.getValue(),devicesData.getUnit()));
                        }


                    }

                    if ("Used".equals(devicesData.getName())){
                        //已用
                        used = used.add(this.unitConversion(devicesData.getValue(),devicesData.getUnit()));
                    }


                }

            }

        }

        cluster.setStorageCount(total);
        cluster.setStorageUsed(used);
        cluster.setStorageMount(mount);
        cluster.setStorageLocal(local);


        if (total.compareTo(BigDecimal.ZERO) > 0){
            cluster.setStorageUse(used.divide(total,4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100)));
        }

        if (insert){
            clusterMapper.insert(cluster);
        }else {
            clusterMapper.updateById(cluster);
        }
        return cluster;
    }

    /**
     * 记录虚拟机集群主机参数
     * @param child
     */
    public void saveOrUpdateHost(VirtuChildResult child,RealVirtualCluster cluster,VirtulResultChild resultChild){

        RealVirtualHost host = hostMapper.selectByClusterIdAndIp(cluster.getId(),resultChild.getLabel());
        Boolean insert = false;
        if (host==null){
            host = new RealVirtualHost();
            insert = true;
            host.setClusterId(cluster.getId());
            host.setIp(resultChild.getLabel());
            host.setId(UUID.randomUUID().toString().replace("-", ""));
        }
        host.setFdn(resultChild.getFdn());
        DevicesMonitors monitor = this.getMonitors(resultChild.getFdn());
        for (DevicesCounters counters : monitor.getMonitors()){

            if ("VmwareHostStatus".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("ConnectionState".equals(devicesData.getName())){
                        //开机数
                        host.setStatus(devicesData.getValue());
                    }

                }
            }

            //cpu
            if ("VmwareHostCpu".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("Utilization".equals(devicesData.getName())){
                        host.setCpuUsageRate(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Capacity".equals(devicesData.getName())){
                        host.setCpuCount(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Speed".equals(devicesData.getName())){
                        host.setCpuSpeed(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Used".equals(devicesData.getName())){
                        host.setCpuUsed(new BigDecimal(devicesData.getValue()));
                    }

                    if ("CPU cores".equals(devicesData.getName())){
                        host.setCpuCores(Double.valueOf(devicesData.getValue()).intValue());
                    }

                }
            }

            //内存
            if ("VmwareHostMemory".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("Utilization".equals(devicesData.getName())){
                        host.setMemeryUsageRate(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Capacity".equals(devicesData.getName())){
                        host.setMemeryCount(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Used".equals(devicesData.getName())){
                        host.setMemeryUsed(new BigDecimal(devicesData.getValue()));
                    }


                }
            }


        }

        if (insert){
            hostMapper.insert(host);
        }else {
            hostMapper.updateById(host);
        }

    }

    /**
     * 记录虚拟机集群虚拟机参数
     * @param child
     */
    public void saveOrUpdateItem(VirtulResultChild child,String name,String id){

        RealVirtualItem item = itemMapper.selectByName(name);
        Boolean insert = false;
        if (item == null){
            item = new RealVirtualItem();
            insert = true;

            item.setName(name);
            item.setId(UUID.randomUUID().toString().replace("-", ""));
        }
        item.setStatus("0");
        item.setClusterId(id);
        DevicesMonitors monitor = this.getMonitors(child.getFdn());
        for (DevicesCounters counters : monitor.getMonitors()){

            if ("VmwareVmStatus".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){
                    if ("PowerState".equals(devicesData.getName())){
                        //开机数
                        item.setStatus("2".equals(devicesData.getValue())?"1":"0");
                    }

                }
            }

//            //cpu
            if ("VmwareVmCpu".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("Utilization".equals(devicesData.getName())){
                        item.setCpuUsageRate(new BigDecimal(devicesData.getValue()));
                    }

                    if ("CPU cores".equals(devicesData.getName())){
                        item.setCpuKernelNum(Double.valueOf(devicesData.getValue()).intValue());
                    }

                    if ("Used".equals(devicesData.getName())){
                        item.setCpuUsed(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Capacity".equals(devicesData.getName())){
                        item.setCpuCount(new BigDecimal(devicesData.getValue()).divide(new BigDecimal(1000),BigDecimal.ROUND_CEILING));
                    }
                }
            }

            //内存
            if ("VmwareVmGuestMemory".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("Utilization".equals(devicesData.getName())){
                        if (new BigDecimal(devicesData.getValue()).compareTo(new BigDecimal(100))>0){
                            item.setMemeryUsageRate(new BigDecimal(0));
                        }else{
                            item.setMemeryUsageRate(new BigDecimal(devicesData.getValue()));
                        }

                    }

                    if ("Capacity".equals(devicesData.getName())){
                        item.setMemeryCount(this.unitGbConversion(devicesData.getValue(),devicesData.getUnit()));
                    }

                    if ("Used".equals(devicesData.getName())){
                        item.setMemeryUsed(new BigDecimal(devicesData.getValue()));
                    }
                }
            }

            //存储
            if ("VmwareVmStorageSummary".equals(counters.getType())){
                for (DevicesData devicesData :counters.getCounters()){

                    if ("Utilization".equals(devicesData.getName())){
                        item.setStorageUse(new BigDecimal(devicesData.getValue()));
                    }

                    if ("Committed".equals(devicesData.getName())){
                        item.setStorageMount(this.unitGbConversion(devicesData.getValue(),devicesData.getUnit()));
                    }

                }
            }


        }

        if (insert){
            itemMapper.insert(item);
        }else {
            itemMapper.updateById(item);
        }

    }


    //全按照TB来
    private BigDecimal unitConversion(String size,String unit){

        //处理数值过大问题
        size = this.dealE(size);

        if (StringUtil.isEmpty(size) || size.equals("0")){
            return new BigDecimal(0);
        }

        if ("GB".equals(unit)){
            return new BigDecimal(size).divide(new BigDecimal(1024),BigDecimal.ROUND_CEILING);
        }
        if ("MB".equals(unit)){
            return new BigDecimal(size).divide(new BigDecimal(1024),BigDecimal.ROUND_CEILING).divide(new BigDecimal(1024),BigDecimal.ROUND_CEILING);
        }
        return new BigDecimal(size);
    }

    //全按照GB来
    private BigDecimal unitGbConversion(String size,String unit){

        //处理数值过大问题
        size = this.dealE(size);

        if (StringUtil.isEmpty(size) || size.equals("0")){
            return new BigDecimal(0);
        }

        if ("MB".equals(unit)){
            return new BigDecimal(size).divide(new BigDecimal(1024),BigDecimal.ROUND_CEILING);
        }
        return new BigDecimal(size);
    }



    public String dealE(String size){
        if (!size.contains("E")){
            return size;
        }
        String[] sizes = size.split("E");

        return new BigDecimal(sizes[0]).multiply(new BigDecimal(10).pow(Integer.parseInt(sizes[1]))).toString();
    }

    public RealVirtualCluster getRealVirtualClusterByIpAndName(String ip , String name){
        return clusterMapper.selectByNameAndIp(name,ip);
    }

    public List<RealVirtualHost> getHostsById(String id){
        return hostMapper.selectByClusterId(id);
    }

    public RealVirtualItem getItem(String name){
        return itemMapper.selectByName(name);
    }

}
